/*!
 * \file Mutex.h
 * \brief Mutex implementation.
 * \author Nus
 * \date 2008/03/13 01:50
 */

#ifndef __MUTEX_H__
#define __MUTEX_H__

#include "Debug.h"
#include "MutualExcl.h"

/*!
 * \class Mutex
 * \brief Mutex class.
 */
class Mutex : public MutualExcl
{
public:
  //! \brief Default constructor.
  Mutex();
  
  //! \brief Default destructor.
  virtual ~Mutex();

  //! \brief Lock mutex.
  virtual s32 lock(void) {
    ASSERT_C(mStatus == 0);
    return pthread_mutex_lock(&mMutex);
  }

  //! \brief Unlock mutex.
  virtual s32 unlock(void) {
    ASSERT_C(mStatus == 0);
    return pthread_mutex_unlock(&mMutex);
  }

  //! \brief Try to mutex.
  virtual s32 trylock(void) {
    ASSERT_C(mStatus == 0);
    return pthread_mutex_trylock(&mMutex);
  }
  
  //! \brief Get mutex object.
  pthread_mutex_t* getMutex(void) {
    return &mMutex;
  }
  
protected:
  pthread_mutex_t mMutex;         //!< Mutex.

private:
  // None...

};



/*!
 * \class AutoMutex
 * \brief Auto mutex class.
 *
 * Use this class to automatically lock your mutex.
 */
class AutoMutex
{
public:
  //! \brief Constructor.
  AutoMutex(Mutex* mtx)
      : mpMutex(mtx)
  {
    ASSERT_C(mpMutex != NULL);
    mpMutex->lock();
  }

  //! \brief Default destructor.
  ~AutoMutex() {
    mpMutex->unlock();
  }

protected:
  // None...

private:
  Mutex* mpMutex;

  //! \brief Default constructor.
  //! \warning Unused function.
  AutoMutex();

};

#endif
